AWSで安全なデータ破棄の仕組みを構築してみた
こんにちは、nkhrです。
オンプレ環境では、データ漏洩(第三者による意図しないデータ取得)を防ぐために、メディア破棄の統制を行っていると思います。クラウドでは、利用者による物理的なメディア破棄が行えないため、統制を行う場合は別の方法を考える必要があります。
クラウド環境で利用できるデータ破棄の方法として、「Cryptographic Erase(CE:暗号化消去)」があります。
今回は、下記のブログで紹介されている暗号化消去(CE)を試してみました。暗号化消去は、NIST 800-88にも記載されている方法です。
クラウドにおける安全なデータの廃棄(Amazon Web Service ブログ)
NIST 800-88や暗号化消去(CE)って何?
NIST 800-88
NIST 800-88(媒体のサニタイズに関するガイドライン)は、メディア破棄の統制を定めるために広く利用されているガイドラインです。(NIST 800-88 Rev.1、IPAによる日本語版はリンク先を参照)
3つのサニタイズ方法が定義されており、データ機密性により適する手法を選択します。
- 削除(Clean)- デバイス再利用が可能:新しい値での上書きや、工場出荷時の状態へのリセット
- 除去(Purge)- デバイス再利用が可能:最先端のデータ復元技術を使っても、対象データが復元できない状態にする
- 破棄(Destroy)- デバイス再利用不可:最先端のデータ復元技術を使っても、どの破壊部分からも対象データが復元できない状態にする
暗号化消去
データを保存時に暗号化し、破棄時に暗号鍵を削除します。これにより、暗号化データを回復不能にします。NIST 800-88では、除去手法に分類されています。適用する場合は、以下の点に注意が必要です。
- 保存を開始する前に、暗号化が有効になっていること
- 適切な暗号鍵の強度や、暗号アルゴリズム/利用モードを使用していること
- 暗号鍵の管理が適切に行われていること
- 暗号鍵のバックアップが存在する場合、適切に保護されていること(また適切に削除されること)
ブログの流れ
ためしてみたコードを参照したい方は、「暗号化消去のリソース作成」を参照してください。
- 前提条件
- 今回のブロクで試す構成の前提条件を整理しています。組織の要件に合わせて前提を定義する必要があります。
- データ暗号化について
- 暗号化消去のリソース作成
- 動作確認
- 実際に暗号化消去を行い、消去通知を受け取ります
前提条件
対象としたサービス
今回は、以下のサービスの暗号化消去を試してみました。
- S3
- Redshift
データのライフサイクルについて
暗号化消去を考える場合、データのライフサイクルごとに鍵を作成する必要があります。(ライフサイクルが終了していないデータがある場合、鍵削除ができない)
今回の検証では、以下のライフサイクルを想定しています。
S3
- Bucket単位のデータライフサイクルを想定(Bucketごとに暗号鍵を作成し、Bucket削除時に鍵削除)
Redshift
- クラスタ単位でデータライフサイクルを想定(Clusterごとに暗号鍵を作成し、Cluster削除時に鍵削除、Snapshotは残さない)
- Snapshotも暗号化されるので、鍵を削除すると復号不可
- データを残したい場合は、S3にUnloadして長期保存用の鍵を作るなど別の考慮が必要
暗号化のための鍵生成
AWS Key Management Service (AWS KMS)を利用して鍵の生成および管理を行います。AWSではいくつかの暗号化方式が利用できます。今回は3番のKMSカスタマー鍵を利用します。
1. S3 Server Side Encryption
S3サービスが管理するデフォルト鍵を利用した暗号化、KMSでの管理外。
2. Customer Masker Key(CMK)※KMS登録なし
利用者側で独自に作成した暗号化鍵、KMS登録しない場合は、KMS管理外。
3. Customer Master Key (CMK) in KMS
KMSサービスで利用する暗号鍵。3パターンの作成方法があります。
- AWS_KMS:KMSで鍵を作成する方法 ★今回の鍵作成はこれを利用★
- EXTERNAL:KMSの外で鍵を生成し、KMSにImportする方法
- Externalの場合は、Importした鍵をAWSが生成した鍵でラップして管理します
- AWS_CLOUDHSM:専用ハードウェアセキュリティモジュール (HSM) インスタンスを使用して鍵作成、暗号化を行う方法
- 指定したリージョンのVPCにある専用CloudHSMクラスター内のHSMインスタンスで、シングルテナント管理
- AWS CloudHSMを利用した暗号化は、KMS利用料金に加えてCloudHSM インスタンス料金が発生
4. AWS managed Key in KMS
codecommitやS3、redshift、EBS、RDSなど、いくつかのAWSサービスは、AWS管理のKMS暗号鍵が利用できます。
Region間で鍵共有する場合
Region間で同じ鍵を利用したい場合は、Multi Region Keyが利用できます。今回はSingle Region Keyを作成しました。Multi Region Keyについては、以下のブログを参照してください。
暗号化消去のために利用するAWSサービス
- AWS KMS (暗号鍵の作成・管理)
- AWS Cloud Trail (ユーザアクティビティやAPI使用状況を追跡)
- 鍵削除の証跡イベントの一部は、CloudTrailで取得
- 暗号化消去の実施有無にかかわらず、AWSアカウントを使い始める際は、CloudTrailを必須で有効化したほうが良いです。以下のブログを参考にしてください
- CloudTiralを監査や、暗号化消去の証明として利用する場合、削除防止・改ざん防止が必要です。実施方法は以下のブログを参考にしてください
- 今回、CloudTrailログの保存先S3バケットは、リソース(S3, Redshift)と同じアカウント内に作成します。実運用では、監査ログ用に隔離されたAWSアカウントを作成し、保存することもあります。
- 鍵削除の証跡イベントの一部は、CloudTrailで取得
データ暗号化について
データ暗号化の考慮点
暗号化消去を行う場合、前提として適切なデータ暗号化が必要です。注意点は以下の通りです。
- 安全な暗号化方式の利用する
- 「電子政府における調達のために参照すべき暗号のリスト(CRYPTREC暗号リスト)」に安全な暗号リストがあります
- AWSのKMSで利用する暗号化については、「AWS Key Management Service暗号化の詳細」を参照してください
- 鍵の管理を適切に行う(鍵のバックアップを含む)
- AWS KMSで一元的に鍵管理を行うことで、バックアップも含めてKMS内で管理できます。
- CMKをKMS外で作成し、Importする場合、Import元のCMKの鍵管理や削除が必要です。
- データ格納前から暗号化が有効になっている
- 暗号化消去を考えている場合は、AWS上にデータを格納する前から暗号化を有効にしておく必要があります。
- どのレイヤーで保護したいかを意識する
- 今回は、物理的なメディア破棄ができない場合の暗号化消去を意識しているためハードウェアレベルの暗号化を想定しています
- アプリケーションレベルの保護が必要な場合は、KMS鍵へのアクセス権限をPolicyで制御するなど別の考慮が必要です
- データの機密レベルを意識する
- データ機密レベルに応じて、どのようなデータ破棄の統制が必要かを検討します
暗号化の強制方法
AWSサービスごとに、暗号化の強制(デフォルト暗号化の設定)方法が異なります。
S3 暗号化設定
S3では「Default Encryption (デフォルト暗号化)」を設定することで、ファイルアップロード時に自動でサーバサイドの暗号化が行われます。
バケット作成時にデフォルト暗号化を有効にせず、暗号化の指定なしにファイルをアップロードした場合は注意が必要です。後でデフォルト暗号化を有効にしても、有効化前のファイルは暗号化されません。暗号化が必要な場合は、バケット作成時に設定するようにしましょう。
S3 Bucket Keyとは
Bucket Keyは、KMSへのアクセス頻度を減らすために利用される鍵でKMSにアクセスする頻度を減らすことができます。(KMSサービスの料金)
「Bucket Key」は、デフォルト「Enable」です。Bucket Keyの詳細については、以下のブログを参考にしてください。
Redshift 暗号化設定
Redshiftでは、暗号化を有効にすると設定前のデータも含めて、クラスター内のデータおよび、スナップショットのデータを全て暗号化します。途中から暗号化を有効にした場合のRedshift動作は、以下の通りです。
- 暗号化を有効にした新規クラスターを起動
- 暗号化設定前のクラスター(既存クラスター)から、新クラスターへデータを移動
- 新しいクラスターのEndpointを変更
途中から暗号化した場合、データ破棄統制の観点からは、既存クラスターの破棄統制が行えません。そのため、暗号化消去を考える場合は、利用前から暗号化を有効にしておきましょう。
KMS暗号化後のデータアクセス制御
KMS鍵の利用制御は、Key PolicyとIAM Policyで行います。Policyが正しく設定されていない場合、データのアップロードやダウンロードができなくなります。KMSのPolicy制御については、下記のブログを参考にしてください。
- 【KMS】デフォルトのキーポリシーについて調べてみた
- AWS KMS CMK(Customer Master Key)のキーポリシーとIAMポリシーの組み合わせのアクセス制御と、キーポリシーのみのアクセス制御を試して設定の違いをみてみた
暗号化消去のリソース作成
ここからが実際のやってみたです。以下のイメージを構築します。
1. auditlogBucket&CloudTrail作成(手動作成)
事前に、監査ログ保存用のS3バケット作成と、CloudTrailの有効化を行います。
Auditlog Bucket 作成
今回は以下の設定で作成しました。Object Lock(削除防止)は一度有効化すると無効化できません。ログの保存要件を踏まえて、Object Lockの適切なモード/期間を設定します。Object Lockを設定したBucketは、空であれば削除可能です。
- Block all public access
- Bucket Versioning enabled
- Default encryption enabled (SSE-S3)
- Object Lock enabled
- Default retention enabled
- Default retention mode Governance
- Default retention period 10
CloudTrail設定
ログ出力先は、手動で作成したAuditlog Bucketにします。今回はCloudTrailから作成されるLog fileに対してSSE-KMSを有効化しません。要件に応じて、有効化してください。
ネットワークリソースの作成
以下のネットワークリソースは事前に作成しています。(Cloudformationテンプレートに含みません)
- VPC
- Public Subnet ※EC2/Redshiftの配置(通常、RedshiftはPrivate Subnetに配置すべきです)
- Route Table
- KeyPair
- S3 Gateway Endpoint
2. 削除の対象外リソース作成
暗号化消去の対象外(削除しない)リソースを作成します。サンプルコードは、以下のリソースを作成します。
- Lambda
- Lambda用Role
- EC2
- EC2用Role & InstanceProfile
- SecurityGroup
- Inboundを許可せず、Session Manager経由の接続のみ可
- SNS Topic
- CloudFormationで作成後に、指定したメールアドレスにConfirmationメールが届くのでConfirmが必要
- SNS Topic Policy
- EventBridgeからSNS TopicにPushするためのPolicy
- Event Rule
- KMS Keyの「CancelKeyDeletion」、 「ScheduleKeyDeletion」、 「DeleteKey」イベントをメール通知するルールを設定
- 鍵の完全削除の通知のために、EventBridgeのdetail-type「KMS CMK Deletion」のイベントを設定
- EventBrigeは同じRegionのCloudTrailのイベントのみ取得可能
サンプルコード
AWSTemplateFormatVersion: '2010-09-09' Parameters: VpcId: Type: String SubnetId: Type: String EC2AMI: Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 KeyName: Type: AWS::EC2::KeyPair::KeyName Email: Type: String Resources: LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com MaxSessionDuration: 36000 ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: lambda-s3empty-role PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - s3:ListBucket - s3:ListBucketVersions - s3:DeleteObject - s3:DeleteObjectVersion Resource: '*' Path: "/" RoleName: test-lambda-s3empty-role LambdaForS3Empty: Type: AWS::Lambda::Function Properties: FunctionName: empty-to-s3 Runtime: python3.8 Handler: index.lambda_handler Role: !GetAtt LambdaExecutionRole.Arn Timeout: 60 Code: ZipFile: | import json import boto3 import cfnresponse s3 = boto3.resource('s3') def lambda_handler(event, context): bucket = event['ResourceProperties']['BucketName'] try: bucket = s3.Bucket(bucket) if event['RequestType'] == 'Delete': bucket.object_versions.delete() bucket.objects.all().delete() sendResponseCfn(event, context, cfnresponse.SUCCESS) except Exception as e: print(e) sendResponseCfn(event, context, cfnresponse.FAILED) def sendResponseCfn(event, context, responseStatus): response_body = {'Status': responseStatus, 'Reason': 'Log stream name: ' + context.log_stream_name, 'PhysicalResourceId': context.log_stream_name, 'StackId': event['StackId'], 'RequestId': event['RequestId'], 'LogicalResourceId': event['LogicalResourceId'], 'Data': json.loads("{}")} cfnresponse.send(event, context, responseStatus, response_body) EC2Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: ec2.amazonaws.com MaxSessionDuration: 36000 ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonS3FullAccess - arn:aws:iam::aws:policy/AmazonRedshiftFullAccess - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore Policies: - PolicyName: kms-key-usage-policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - kms:Decrypt - kms:Encrypt - kms:GenerateDataKey Resource: '*' Path: "/" RoleName: test-ec2-role IAMInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref EC2Role Path: "/" EC2TestInstance: Type: AWS::EC2::Instance DeletionPolicy: Delete CreationPolicy: ResourceSignal: Timeout: PT30M Properties: IamInstanceProfile: !Ref IAMInstanceProfile ImageId: !Ref EC2AMI InstanceType: t3a.micro KeyName: !Ref KeyName InstanceInitiatedShutdownBehavior: stop DisableApiTermination: false Monitoring: false BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeType: gp3 DeleteOnTermination: true Encrypted: true VolumeSize: 20 NetworkInterfaces: - AssociatePublicIpAddress: true DeviceIndex: 0 SubnetId: !Ref SubnetId GroupSet: - !Ref EC2SecurityGroup UserData: Fn::Base64: !Sub - | #!/bin/bash yum update -y echo '---------------- update aws cli ----------------' yum -y install jq gcc curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip ./aws/install echo '---------------- install amazon redshift rsql ----------------' yum -y install unixODBC curl "https://s3.amazonaws.com/redshift-downloads/drivers/odbc/1.4.40.1000/${ODBCFILE}" -o ./${ODBCFILE} yum -y --nogpgcheck localinstall ./${ODBCFILE} echo "export ODBCINI=\$HOME/.odbc.ini" >> /etc/profile echo "export ODBCSYSINI=/opt/amazon/redshiftodbc/Setup" >> /etc/profile echo "export AMAZONREDSHIFTODBCINI=/opt/amazon/redshiftodbc/lib/64/amazon.redshiftodbc.ini" >> /etc/profile curl "https://s3.amazonaws.com/redshift-downloads/amazon-redshift-rsql/1.0.1/${RSQLFILE}" -o ./${RSQLFILE} rpm -i ./${RSQLFILE} echo '---------------- send cfn-signal ----------------' /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource EC2TestInstance --region ${AWS::Region} - { RSQLFILE: "AmazonRedshiftRsql-1.0.1-1.x86_64.rpm", ODBCFILE: "AmazonRedshiftODBC-64-bit-1.4.40.1000-1.x86_64.rpm" } EC2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VpcId GroupName: ec2-test-securitygroup GroupDescription: ec2-test-securitygroup SNSTopic: Type: AWS::SNS::Topic Properties: TopicName: notify-mail-cloudtrail-kms-event Subscription: - Endpoint: !Ref Email Protocol: email SNSTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: Topics: - !Ref SNSTopic PolicyDocument: Version: 2012-10-17 Statement: - Sid: TopicPolicy Effect: Allow Principal: Service: events.amazonaws.com Action: - sns:Publish Resource: !Ref SNSTopic KMSKeyDeletionRule: Type: AWS::Events::Rule Properties: Name: cloudtrail-test-cf-event-rule State: ENABLED EventPattern: | { "source": ["aws.kms"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventSource": ["kms.amazonaws.com"], "eventName": ["CancelKeyDeletion", "ScheduleKeyDeletion", "DisableKey", "DeleteKey"] } } Targets: - Arn: !Ref SNSTopic Id: KMSKeyAlert CMKDeletionRule: Type: AWS::Events::Rule Properties: Name: cloudtrail-test-aws-event-rule State: ENABLED EventPattern: | { "source": ["aws.kms"], "detail-type": ["KMS CMK Deletion"] } Targets: - Arn: !Ref SNSTopic Id: KMSKeyAlert Outputs: EC2SecurityGroupId: Value: !GetAtt EC2SecurityGroup.GroupId EC2TestInstancePrivateIP: Value: !GetAtt EC2TestInstance.PrivateIp LambdaArn: Value: !GetAtt LambdaForS3Empty.Arn SendEmail: Value: !Ref Email
3. S3Bucket & KMS Key作成
サンプルでは以下のリソースを作成しています。
- S3 Bucket
- Custom Resource (LambdaによるS3 Bucket削除用)
- KMS Key
サンプルコード
AWSTemplateFormatVersion: '2010-09-09' Parameters: S3BucketName: Type: String Default: ttn-test-encrypt-data AuditBucketName: Type: String Default: ttn-test-audit-logs LambdaFunctionName: Type: String Default: empty-to-s3 Resources: LambdaForS3Empty: Type: Custom::cleanupbucket Properties: ServiceToken: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunctionName}' BucketName: !Ref S3BucketName DependsOn: Bucket Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref S3BucketName AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: TRUE BlockPublicPolicy: TRUE IgnorePublicAcls: TRUE RestrictPublicBuckets: TRUE LoggingConfiguration: DestinationBucketName: !Ref AuditBucketName LogFilePrefix: !Sub s3accesslogs/${S3BucketName}/ BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: aws:kms KMSMasterKeyID: !GetAtt S3BucketSSEKMS.KeyId BucketKeyEnabled: true S3BucketSSEKMS: Type: AWS::KMS::Key Properties: Description: s3 kms key sample Enabled: true # SYMMETRIC_DEFAULT is AES-256-GCM KeySpec: SYMMETRIC_DEFAULT MultiRegion: false EnableKeyRotation: true PendingWindowInDays: 7 KeyPolicy: Version: 2012-10-17 Id: s3-sse-key-default Statement: - Sid: Enable IAM User Permissions Effect: Allow Principal: AWS: !Sub arn:aws:iam::${AWS::AccountId}:root Action: 'kms:*' Resource: '*' S3KmsKeyAlias: Type: AWS::KMS::Alias Properties: AliasName: alias/test-s3-kms-key TargetKeyId: !Ref S3BucketSSEKMS Outputs: KmsKeyAlias: Value: !Ref S3KmsKeyAlias BucketArn: Value: !GetAtt Bucket.Arn
サンプルを実行すると、S3 BucketとS3 BucketのKMS Keyが自動生成されます。
4. Redshift & KMS Key作成
サンプルでは以下のリソースを作成しています。
- Redshift Cluster (SubnetGroup & Cluster Group)
- SecurityGroup
- KMS Key
サンプルコード
AWSTemplateFormatVersion: "2010-09-09" Parameters: VpcId: Type: AWS::EC2::VPC::Id SubnetId: Type: AWS::EC2::Subnet::Id EC2SecurityGroupId: Type: AWS::EC2::SecurityGroup::Id # 作成したEC2にアタッチしたSecurity Groupを選択 ClusterName: Type: String Default: test-redshit MasterUsername: Type: String Default: test_admin MasterUserPassword: # SecretManagerやParameter Storeを利用したほうが良いです Type: String Port: Type: String Default: 5439 Resources: S3AccessRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: redshift.amazonaws.com MaxSessionDuration: 3600 ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonS3FullAccess Policies: - PolicyName: kms-key-usage-policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - kms:Decrypt - kms:Encrypt - kms:GenerateDataKey Resource: '*' Path: "/" RoleName: RedshiftS3AccessRole SubnetGroup: Type: AWS::Redshift::ClusterSubnetGroup Properties: Description: Redshift cluster subnet group SubnetIds: - !Ref SubnetId SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VpcId GroupName: test-redshift-sg GroupDescription: test-redshift-sg SecurityGroupIngress: - IpProtocol: tcp FromPort: !Ref Port ToPort: !Ref Port SourceSecurityGroupId: !Ref EC2SecurityGroupId ClusterParameterGroup: Type: AWS::Redshift::ClusterParameterGroup Properties: Description: 'dwh test redshift' ParameterGroupFamily: redshift-1.0 Parameters: - ParameterName: require_ssl ParameterValue: true Cluster: Type: AWS::Redshift::Cluster Properties: AllowVersionUpgrade: true AquaConfigurationStatus: disabled AvailabilityZone: ap-northeast-1a Classic: false ClusterIdentifier: !Ref ClusterName ClusterParameterGroupName: !Ref ClusterParameterGroup ClusterSubnetGroupName: !Ref SubnetGroup ClusterType: single-node NodeType: dc2.large Encrypted: true EnhancedVpcRouting: true IamRoles: - !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/redshift.amazonaws.com/AWSServiceRoleForRedshift - !GetAtt S3AccessRole.Arn KmsKeyId: !GetAtt RedshiftKMS.KeyId DBName: test Port: !Ref Port MasterUsername: !Ref MasterUsername MasterUserPassword: !Ref MasterUserPassword AutomatedSnapshotRetentionPeriod: 1 ManualSnapshotRetentionPeriod: 1 PreferredMaintenanceWindow: 'Sun:07:00-Sun:07:30' PubliclyAccessible: false VpcSecurityGroupIds: - !Ref SecurityGroup RedshiftKMS: Type: AWS::KMS::Key Properties: Description: redshift kms key sample Enabled: true # SYMMETRIC_DEFAULT is AES-256-GCM KeySpec: SYMMETRIC_DEFAULT MultiRegion: false EnableKeyRotation: true PendingWindowInDays: 7 KeyPolicy: Version: 2012-10-17 Id: redshift-key-default Statement: - Sid: Enable IAM User Permissions Effect: Allow Principal: AWS: !Sub arn:aws:iam::${AWS::AccountId}:root Action: 'kms:*' Resource: '*' RedshiftKmsKeyAlias: Type: AWS::KMS::Alias Properties: AliasName: alias/test-redshift-kms-key TargetKeyId: !Ref RedshiftKMS Outputs: Cluster: Value: !Ref Cluster Endpoint: Value: !GetAtt Cluster.Endpoint.Address Port: Value: !GetAtt Cluster.Endpoint.Port DatabaseName: Value: Cluster Username: Value: !Ref MasterUsername AccessCmd: Value: !Sub "rsql -h ${Cluster.Endpoint.Address} -U ${MasterUsername} -d test"
サンプルを実行すると、Redshift ClusterとKMS Keyが自動生成されます。
データ投入とKMS暗号化確認
S3ファイルアップロード
[ec2-user@ip-10-0-0-33 ~]$ echo "test file" > test.txt [ec2-user@ip-10-0-0-33 ~]$ aws s3 cp test.txt s3://ttn-test-encrypt-data/ upload: ./test.txt to s3://ttn-test-encrypt-data/test.txt
アップロードしたファイルは、自動でKMS鍵により、サーバサイド暗号化されます。(ファイルの「プロパティ>サーバ側の暗号化設定」で確認)
Redshiftへの接続
S3バケットのKMS暗号化ファイルをRedshiftにコピーできるか確認します。
[ec2-user@ip-10-0-0-33 ~]$ rsql -h test-redshit.cxrqsub7rc82.ap-northeast-1.redshift.amazonaws.com -U test_admin -d test (test-redshit) test_admin@test=# CREATE TABLE test(col1 INT, col2 VARCHAR(100), col3 INT); (test-redshit) test_admin@test=# COPY test from 's3://ttn-test-encrypt-data/redshift/copy_data.csv' iam_role 'arn:aws:iam:::role/RedshiftS3AccessRole' csv IGNOREHEADER 1; INFO: Load into table 'test' completed, 2 record(s) loaded successfully. (test-redshit) test_admin@test=# select * from test; col1 | col2 | col3 ------+------+------ 1 | aaa | 3 2 | bbb | 4 (2 rows)
暗号化消去の動作確認
S3Bucket削除 & KMS鍵削除
CloudFormationスタックを削除し、S3 BucektとKMS鍵を削除します。
KMS Keyは削除保留中の状態になります。
Event Bridgeにより、ScheduleKeyDeletion(スケジュール削除)イベントの結果がメール通知されます。
Redshiftクラスター削除 & KMS鍵削除
CloudFormationスタックを削除し、RedshiftとKMS Keyを削除します。
Event Bridgeにより、ScheduleKeyDeletionイベントの結果がメール通知されます。メール内容は、S3 Bucket用のKMS鍵の削除で送信されるメッセージと同様です。
削除予約したKMS鍵の復元
KMS鍵は、削除保留期間の設定が必須であるため(最低7日)、削除保留期間中は鍵の削除をキャンセルできます。
完全削除の通知
削除保留期間が経過した鍵は、AWSにより自動で削除されます。EventBridge経由のSNS通知で以下のようなメールを取得できます。
まとめ
今回は、データ消去の統制を行うための仕組みを構築し、鍵削除の通知をメールで受け取れることを確認しました。
通知メール内容は、少し読みにくいので、SNSのメール通知前に、EventBridgeと他のサービス(LambdaやStep Function)を組み合わせて、レポートを作成したり、作成レポートをS3保存してもよいと思います。
以上、nkhrでした。
参考資料
- クラウドにおける安全なデータの廃棄(Amazon Web Service ブログ)
- クラウドにおける安全なデータの廃棄(実践編)****(****Amazon Web Service ブログ)
- 電子政府における調達のために参照すべき暗号のリスト(CRYPTREC暗号リスト)
- AWS Key Management Service暗号化の詳細